package pers.w.chaptertalk.reader;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.style.ImageSpan;
import android.util.Log;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;

import androidx.annotation.NonNull;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Properties;

import pers.w.chaptertalk.R;
import pers.w.chaptertalk.funs.ChapterInfo;
import pers.w.chaptertalk.funs.Fun;
import pers.w.chaptertalk.funs.IReader;
import pers.w.chaptertalk.funs.ISetting;
import pers.w.chaptertalk.funs.db.Tab_Book;
import pers.w.chaptertalk.funs.db.Tab_BookProgress;

class ReaderControl implements IReader, ISetting {
    private TextView prepareView, tv_reader;
    private ReaderActivity reader;
    private HashMap<String, String> talksCount;
    private int start;

    ReaderControl(ReaderActivity reader, TextView prepareView, TextView tv_reader) {
        this.reader = reader;
        this.tv_reader = tv_reader;
        this.prepareView = prepareView;

        load_setting();

    }

    void setTalksCount(HashMap<String, String> talksCount) {
        this.talksCount = talksCount;
    }

    @Override
    public void load_setting() {

        Properties properties = new Properties();
        try {
            InputStream is = reader.openFileInput(CONFIG_NAME);
            properties.load(is);
            setTextSize(Integer.parseInt(properties.getProperty(TEXT_SIZE, "5")));
            setFont(properties.getProperty(FONT_PATH, ""));
            setTextColor(Integer.parseInt(properties.getProperty(TEXT_COLOR, "-1070386381")));//0xC0333333‬
            setBackgroundColor(Integer.parseInt(properties.getProperty(BACKGROUND_COLOR, "0xFFFFCC8D")));
            setRowSpacing(Integer.parseInt(properties.getProperty(ROW_SPACING, "10")));
            setParagraph_spacing(Integer.parseInt(properties.getProperty(PARAGRAPH_SPACING, "20")));
            setOrientation(Integer.parseInt(properties.getProperty(ORIENTATION, "0")));
            setScreenOnTime(properties.getProperty(SCREENON_TIME, "0"));
            is.close();
        } catch (IOException e) {
            e.printStackTrace();
            //设置默认值，如果没用设置，不至于出错
            defaultSetting();
        }

    }

    void defaultSetting() {
        setFont("");
        setScreenOnTime("0");
        setTextColor(-1070386381);
        setBackgroundColor(0xFFFFCC8D);
        setParagraph_spacing(20);
        setRowSpacing(10);
        setTextSize(5);
        setOrientation(LinearLayout.HORIZONTAL);
    }

    private final static String TEXT_SIZE = "text_size", FONT_PATH = "font_path",
            TEXT_COLOR = "text_color", BACKGROUND_COLOR = "background_color",
            ROW_SPACING = "row_spacing", PARAGRAPH_SPACING = "paragraph_spacing", ORIENTATION = "orientation",
            SCREENON_TIME = "screenOnTime", CONFIG_NAME = "reader_config";

    @Override
    public void save_setting() {
        Properties properties = new Properties();

        try {

            OutputStream out = reader.openFileOutput(CONFIG_NAME, Context.MODE_PRIVATE);

            properties.setProperty(TEXT_SIZE, String.valueOf(textSize));
            properties.setProperty(FONT_PATH, fontPath);
            properties.setProperty(TEXT_COLOR, String.valueOf(textColor));
            properties.setProperty(BACKGROUND_COLOR, String.valueOf(backgroundColor));
            properties.setProperty(ROW_SPACING, String.valueOf(rowSpacing));
            properties.setProperty(PARAGRAPH_SPACING, String.valueOf(paragraph_spacing));
            properties.setProperty(ORIENTATION, String.valueOf(orientation));
            properties.setProperty(SCREENON_TIME, screenOnTime);

            properties.store(out, null);
            out.close();
            if (Fun.isDebug()) Log.d("config", "save_setting: true");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    int getBackgroundColor() {
        return backgroundColor;
    }

    private int backgroundColor;

    void setBackgroundColor(int color) {
        backgroundColor = color;
        tv_reader.setBackgroundColor(color);
        prepareView.setBackgroundColor(color);
    }

    private int rowSpacing;

    int getRowSpacing() {
        return rowSpacing;
    }

    void setRowSpacing(int rowSpacing) {
        this.rowSpacing = rowSpacing;
        tv_reader.setLineSpacing(rowSpacing, 1);
        prepareView.setLineSpacing(rowSpacing, 1);
    }


    private int orientation;

    int getOrientation() {
        return orientation;
    }

    void setOrientation(int orientation) {
        this.orientation = orientation;
    }


    private int textColor;

    int getTextColor() {
        return textColor;
    }

    void setTextColor(int textColor) {
        this.textColor = textColor;
        tv_reader.setTextColor(textColor);
        prepareView.setTextColor(textColor);
    }


    private int textSize;

    int getTextSize() {
        return textSize;
    }

    //在15大小往上加
    void setTextSize(int size) {
        this.textSize = size;
        tv_reader.setTextSize(size + TEXT_SIZE_MIN);
        prepareView.setTextSize(size + TEXT_SIZE_MIN);
    }

    /*public int getCurrentChapterIndex() {
        return currentChapterIndex;
    }

    public void setCurrentChapterIndex(int currentChapterIndex) {
        this.currentChapterIndex = currentChapterIndex;
    }*/


    private int paragraph_spacing;//段落间距

    int getParagraph_spacing() {
        return paragraph_spacing;
    }

    void setParagraph_spacing(int paragraph_spacing) {
        this.paragraph_spacing = paragraph_spacing;
    }

    private ChapterInfo chapter;//该章节的信息

    private ChapterInfo getChapter() {
        return chapter;
    }

    void setProgress(Tab_BookProgress.BookProgress progress) {
        this.progress = progress;
    }

    Tab_BookProgress.BookProgress getProgress() {
        return progress;
    }

    private Tab_BookProgress.BookProgress progress;


    public String getScreenOnTime() {
        return screenOnTime;
    }

    public void setScreenOnTime(String screenOnTime) {
        this.screenOnTime = screenOnTime;
    }

    private String screenOnTime;

    void resetProgress(int startOrEndOrNoChange) {//新章节要跳转的进度
        progress.chapterID = chapter.getChapterID();
        if (startOrEndOrNoChange == BEGIN) {
            progress.progress = 0;
        } else if (startOrEndOrNoChange == END) {
            progress.progress = pages.size() > 0 ? pages.get(pages.size() - 1).start : 0;
        }

    }

    void update_SQL(long bookID) {
        if (bookID > 0) {
            Tab_Book tab_book = new Tab_Book(reader);
            tab_book.getTab_bookProgress().update(bookID, progress.chapterID, progress.progress);
            tab_book.close();
        }
    }

    void setChapter(ChapterInfo chapter) {
        this.chapter = null;
        this.chapter = chapter;
        //progress.progress = 0;//end = this.chapter.getContent().length();
    }

    boolean isClickSpan() {
        return clickSpan;
    }

    void resetClickSpan() {
        this.clickSpan = false;
    }

    private boolean clickSpan = false;

    private void resetSpannableString() {

        final int ALIGN_BOTTOM = 0;
        final int ALIGN_BASELINE = 1;
        final int ALIGN_CENTER = 2;//没搞懂这个,感觉2个的定义不太符合显示效果ALIGN_BASELINE，ALIGN_CENTER

        spannableString = new SpannableString(this.getChapter().getContent());
        //context.getResources().getDrawable(R.drawable.talk);
        final Drawable line_drawable = reader.getResources().getDrawable(R.drawable.space);//border
        float ascent = 0 - prepareView.getPaint().getFontMetrics().ascent;
        // float drawHeight =Math.max(ascent, 45);
        final Drawable drawable = reader.getResources().getDrawable(R.drawable.space);
        drawable.setBounds(0, 0, 75, 1);


        line_drawable.setBounds(0, 0, (int) prepareView.getPaint().measureText("缩进"), (int) (ascent + paragraph_spacing));
        int index = -1;


        ClickableSpan clickableSpan;
        String content = chapter.getContent();
        String tag, count;
        int start;
        while ((index = content.indexOf(ChapterInfo.TAG_STR, index + ChapterInfo.TAG_STR.length())) != -1) {
            //画一个段落高,line_drawable的宽度为1，就是在段落最开始看不到而已，但是占用这个行的高度，造成视觉上的段落高度
            // if (index+3<=spannableString.length())
            spannableString.setSpan(new ImageSpan(line_drawable, ALIGN_BASELINE), index + 3, index + 4, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
            //如果不显示本章说，直接跳过绘制
            if (!reader.controlWindow.showChapterTalks()) continue;
            start = Math.max(index - 50, 0);
            tag = Fun.getMD5(content.substring(start, index));
            if (talksCount != null) {
                count = talksCount.get(tag);
                if (count == null) count = "0";
                else if (count.length() > 2) count = "99";
            } else count = "0";
            clickableSpan = new ClickableSpan(tag);
            //先画个标志
            spannableString.setSpan(new MyImageSpan(drawable, count), index, index + 1, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);//SPAN_INCLUSIVE_EXCLUSIVE前包括，后不包括
            //给标志设置按钮效果
            spannableString.setSpan(clickableSpan, index, index + 1, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
        }
    }

    //HashMap<String,String>
    static class TextPage {
        int start, end;
    }

    List<TextPage> getPages() {
        return pages;
    }

    TextPage getPage(int index) {
        return pages.get(index);
    }

    TextPage getCurPage() {
        return pages.get(curPage);
    }

    int getPagesSize() {
        return pages.size();
    }

    private List<TextPage> pages = new ArrayList<>();

    int getCurPageIndex() {
        return curPage;
    }

    private int curPage;


    private SpannableString spannableString;

    //跳转到进度所在的页
    void seekToProgress() {
        for (int i = pages.size() - 1; i >= 0; i--) {
            if (progress.progress >= pages.get(i).start) {
                curPage = i;
                showPage(curPage);
                return;
            }
        }
    }

    private void resetPrepareViewLayout() {
        RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(prepareView.getLayoutParams());
        lp.leftMargin = lp.rightMargin = lp.topMargin = lp.bottomMargin = 0;
        prepareView.setLayoutParams(lp);
    }


    /**
     * 把章节内容分割成数个段落，这样就可以更好的控制
     */
    void splitPage() {
        pages.clear();
        resetSpannableString();
        //long time = System.currentTimeMillis();
        //int lineHeight = prepareView.getLineHeight();
        prepareView.setVisibility(View.VISIBLE);

        resetPrepareViewLayout();
        int want_show_Height = tv_reader.getHeight() - paragraph_spacing - tv_reader.getLineHeight() ;//原来getLineHeight（）/2，会滚动
        want_show_Height = want_show_Height - tv_reader.getPaddingTop() - tv_reader.getPaddingBottom();


        /*方法3*/
        int sp_length = spannableString.length();
        prepareView.setText(spannableString.subSequence(0, sp_length));
        //Log.d("time", "runtime: " + (System.currentTimeMillis() - time));
        int lines = prepareView.getLineCount();
        int start = 0;
        Rect rect = new Rect();
        int prePageBottom = 0;
        TextPage page;

        for (int i = 0; i < lines; i++) {
            if (i == lines - 1) {//最后一行了
                page = new TextPage();
                page.start = start;
                page.end = prepareView.getLayout().getLineEnd(i);
                pages.add(page);
                break;
            }
            prepareView.getLineBounds(i, rect);
            if (rect.bottom - prePageBottom > want_show_Height) {
                prePageBottom = rect.top;
                page = new TextPage();
                page.start = start;
                page.end = prepareView.getLayout().getLineStart(i);
                start = page.end;
                pages.add(page);

            }
        }
        prepareView.setVisibility(View.INVISIBLE);
    }

    void showPreparePage(int change) {//变大说明上一页，小下一页
        int step = curPage + (change <= 0 ? 1 : -1);
        if (step < 0) {
            prepareView.setText("\n\n\n\n\n\t上一章");
        } else if (step >= pages.size()) {
            prepareView.setText("\n\n\n\n\n\t下一章");
        } else {
            TextPage page = pages.get(step);
            prepareView.setText(spannableString.subSequence(page.start, page.end));
        }
    }

    private boolean showPage(int position) {
        if (pages.size() > position) {
            TextPage page = pages.get(position);
            if (reader.hasWindowFocus())//有焦点才更新
            {
                updateTV_Reader(page);
            }
            progress.progress = page.start;
            return true;
        }
        return false;
    }

    void updateTV_Reader(TextPage page) {
        tv_reader.setText(spannableString.subSequence(page.start, page.end));
    }

    void updateTV_Reader() {
        updateTV_Reader(getCurPage());
    }

    boolean next() {
        return stepTo(1);
    }

    private boolean stepTo(int step) {
        if (curPage + step >= 0 && curPage + step < pages.size()) {
            curPage += step;
            return showPage(curPage);
        } else
            return false;
    }

    boolean previous() {
        return stepTo(-1);
    }


    String getFontPath() {
        return fontPath;
    }


    private String fontPath;

    void setFont(String path) {

        fontPath = path;
        Typeface typeface = path.equals("") ? Typeface.DEFAULT : Typeface.createFromFile(path);
        // Typeface.createFromAsset(prepareView.getContext().getAssets(), path);  // "fonts/Jinglei.ttf"
        prepareView.setTypeface(typeface);
        tv_reader.setTypeface(typeface);
    }

    class ClickableSpan extends android.text.style.ClickableSpan {
        private String tag;

        ClickableSpan(Object tag) {
            super();
            this.tag = (String) tag;
        }


        @Override
        public void onClick(@NonNull View widget) {
            clickSpan = true;
            onSpanClick(tag);
            //   Toast.makeText(reader.getApplicationContext(), tag, Toast.LENGTH_SHORT).show();
        }
    }

    private void onSpanClick(String tag) {
        if (!reader.spoken_setting.isPlaying())
            reader.talks.show(tag);

    }

    static class MyImageSpan extends ImageSpan {
        private String count;

        MyImageSpan(@NonNull Drawable drawable, String count) {
            super(drawable);
            this.count = count;
        }

        @Override
        public void draw(@NonNull Canvas canvas, CharSequence text, int start, int end, float x, int top, int y, int bottom, @NonNull Paint paint) {
            //super.draw(canvas, text, start, end, x, top, y, bottom, paint);
            int yOffset = y + paint.getFontMetricsInt().ascent + 10;
            float[] pts = {
                    15, 2, 65, 2,
                    65, 2, 65, 43,
                    65, 43, 15, 43,
                    15, 43, 15, 30,
                    15, 30, 2, 20,
                    2, 20, 15, 10,
                    15, 10, 15, 2};
            for (int i = 0; i < pts.length; i += 2) {
                pts[i] += x;
                pts[i + 1] += yOffset;
            }
            canvas.drawLines(pts, paint);
            canvas.save();
            paint.setTextSize(40);
            canvas.drawText(count, 20 + x, 40 + yOffset, paint);
            canvas.restore();
        }
    }
}
